package com.genexususa.eo.google.connection;

import com.genexususa.eo.google.data.*;
import com.google.api.ads.adwords.axis.v201406.cm.*;
import com.google.api.ads.adwords.axis.v201406.mcm.ManagedCustomer;
import com.google.api.ads.adwords.axis.v201406.mcm.ManagedCustomerPage;
import com.google.api.ads.adwords.axis.v201406.mcm.ManagedCustomerServiceInterface;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import java.io.*;
import java.rmi.RemoteException;
import java.util.ArrayList;

public class SyncManager {

    private static final int PAGE_SIZE = 5000;

    public void GetTotalReportForClientsExc(String clientIds, String filePath, Long timeBetweenRequests, int retries){
        String[] clientIdsArray = clientIds.split(";");

        ArrayList<Thread> threads = new ArrayList<Thread>();

        for(String clientId : clientIdsArray){


            GetTotalReportForClientExc totalReport = new GetTotalReportForClientExc(clientId, filePath, retries);
            totalReport.start();
            System.out.println(totalReport.getName() + " started!");
            threads.add(totalReport);
            try {
                Thread.sleep(timeBetweenRequests);
            }catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
                totalReport = new GetTotalReportForClientExc(clientId, filePath, retries);
                totalReport.start();
            }
        }


        for (Thread thread : threads){
            try{
                thread.join();
                System.out.println(thread.getName() + " ended!");
            }catch (InterruptedException e) {
                e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
        }
    }

    public void GetTotalReportForClientExc(String accountId, String filePath) throws Exception{

            GA_Report report = new GA_Report();
            ArrayList<GA_CampaignStats> stats = GetCampaignStatsExc(accountId);
            for (GA_CampaignStats stat : stats) {
                CampaignReport campaignReport = new CampaignReport();
                campaignReport.AdServingOptimizationStatus = stat.AdServingOptimizationStatus;
                campaignReport.BidCeiling = stat.BidCeiling;
                campaignReport.BiddingStrategyType = stat.BiddingStrategyType;
                campaignReport.BidType = stat.BidType;
                campaignReport.BudgetId = stat.BudgetId;
                campaignReport.EndDate = stat.EndDate;
                campaignReport.EnhancedCpcEnabled = stat.EnhancedCpcEnabled;
                campaignReport.FrequencyCapMaxImpressions = stat.FrequencyCapMaxImpressions;
                campaignReport.Id = stat.Id;
                campaignReport.Level = stat.Level;
                campaignReport.Name = stat.Name;
                campaignReport.PricingMode = stat.PricingMode;
                campaignReport.StartDate = stat.StartDate;
                campaignReport.Status = stat.Status;
                campaignReport.TargetContentNetwork = stat.TargetContentNetwork;
                campaignReport.TargetGoogleSearch = stat.TargetGoogleSearch;
                campaignReport.TargetPartnerSearchNetwork = stat.TargetPartnerSearchNetwork;
                campaignReport.TargetSearchNetwork = stat.TargetSearchNetwork;
                campaignReport.TimeUnit = stat.TimeUnit;
                campaignReport.GeoTargetNegativeType = stat.GeoTargetNegativeType;
                campaignReport.GeoTargetPositiveType = stat.GeoTargetPositiveType;
                campaignReport.KeywordMatch = stat.KeywordMatch;
                campaignReport.RealTimeBidding = stat.RealTimeBidding;
                campaignReport.AdvertisingChannelType = stat.AdvertisingChannelType;
                campaignReport.BiddingStrategyId = stat.BiddingStrategyId;
                campaignReport.BiddingStrategyName = stat.BiddingStrategyName;

                report.Campaigns.add(campaignReport);
            }

            ArrayList<AdExtensionLocationReport> extensionLocations = GetAdExtensionLocationReportExc(accountId);
            ArrayList<SitelinksReport> sitelinks = GetFeedItemsSitelinksReportExc(accountId);
            report.Sitelinks = sitelinks;
            ArrayList<LocationExtensionReport> locationExtensions = GetFeedItemsLocationExtensionReportExc(accountId);
            report.LocationExtensions = locationExtensions;
            ArrayList<CallsAdExtensionReport> calls = GetFeedItemsAdExtensionsCallsReportExc(accountId);
            report.Calls = calls;
            ArrayList<PlatformReport> platforms = GetCampaignDevicesExc(accountId);
            ArrayList<LanguageReport> languages = GetCampaignLanguagesExc(accountId);
            ArrayList<KeywordReport> campaignKeywords = GetKeywordsExc(accountId);
            ArrayList<AdGroupReport> adGroups = GetAdGroupStatsExc(accountId);
            ArrayList<ProximityReport> proximities = GetProximitiesExc(accountId);
            ArrayList<LocationReport> locations = GetLocationsExc(accountId);
            getLocationsExtraDataExc(accountId, locations);
            ArrayList<TextAdReport> textAds = GetTextAdsExc(accountId);
            ArrayList<ImageAdReport> imageAds = GetImageAdsExc(accountId);
            ArrayList<AdGroupKeywordReport> adGroupKeywords = GetAdGroupKeywordsExc(accountId);
            report.Budgets = GetBudgetStatsExc(accountId);
            report.Account = GetAccountReportExc(accountId);
            report.Feeds = GetAllFeedsReportExc(accountId);
            ArrayList<AdGroupPlacementReport> adGroupPlacementReports = GetAdGroupPlacementsExc(accountId);
            ArrayList<AdGroupTopicReport> adGroupTopicReports = GetAdGroupTopicsExc(accountId);
            ArrayList<AdGroupInterestReport> adGroupInterestReports = GetAdGroupInterestsExc(accountId);
            ArrayList<AdGroupGenderReport> adGroupGenderReports = GetAdGroupGendersExc(accountId);
            ArrayList<AdGroupAgeReport> adGroupAgeReports = GetAdGroupAgesExc(accountId);
            ArrayList<GA_SitelinksFeedItem> sitelinksFeedItems = GetSitelinksFeedItemReportExc(accountId);
            report.SitelinksFeedItems = sitelinksFeedItems;
            ArrayList<GA_LocationExtensionsFeedItem> locationExtensionsFeedItems = GetLocationExtensionsFeedItemReportExc(accountId);
            report.LocationExtensionsFeedItems = locationExtensionsFeedItems;
            ArrayList<GA_CallsFeedItem> callsFeedItems = GetCallsFeedItemReportExc(accountId);
            report.CallsFeedItems = callsFeedItems;

            //ConversionTrackerManager ctm = new ConversionTrackerManager();

            //report.ConversionTrackers = ctm.GetConversionTrackerStats(accountId);

            // ngonzalez | 11.25.2013 | group obtained totals by campaign
            for (CampaignReport cr : report.Campaigns) {
                Long campaignId = cr.Id;

                // AdGroups
                for (AdGroupReport adGroupReport : adGroups) {
                    if (adGroupReport.CampaignId.equals(campaignId)) {

                        // AdGroupKeywords
                        for (AdGroupKeywordReport adGroupKeywordReport : adGroupKeywords) {
                            if (adGroupKeywordReport.AdGroupId.equals(adGroupReport.Id)) {
                                adGroupReport.AdGroupKeywords.add(adGroupKeywordReport);
                            }
                        }

                        // TextAds
                        for (TextAdReport textAdReport : textAds) {
                            if (textAdReport.AdGroupId.equals(adGroupReport.Id)) {
                                adGroupReport.TextAds.add(textAdReport);
                            }
                        }

                        // ImageAds
                        for (ImageAdReport imageAdReport : imageAds) {
                            if (imageAdReport.AdGroupId.equals(adGroupReport.Id)) {
                                adGroupReport.ImageAds.add(imageAdReport);
                            }
                        }

                        // ngonzalez | 01.29.2014 |
                        for (AdGroupPlacementReport placementReport : adGroupPlacementReports) {
                            if (placementReport.AdGroupId.equals(adGroupReport.Id)) {
                                adGroupReport.AdGroupPlacements.add(placementReport);
                            }
                        }

                        for (AdGroupTopicReport adGroupTopicReport : adGroupTopicReports) {
                            if (adGroupTopicReport.AdGroupId.equals(adGroupReport.Id)) {
                                adGroupReport.AdGroupTopics.add(adGroupTopicReport);
                            }
                        }

                        for (AdGroupInterestReport adGroupInterestReport : adGroupInterestReports) {
                            if (adGroupInterestReport.AdGroupId.equals(adGroupReport.Id)) {
                                adGroupReport.AdGroupInterests.add(adGroupInterestReport);
                            }
                        }

                        for (AdGroupGenderReport adGroupGenderReport : adGroupGenderReports) {
                            if (adGroupGenderReport.AdGroupId.equals(adGroupReport.Id)) {
                                adGroupReport.AdGroupGenders.add(adGroupGenderReport);
                            }
                        }

                        for (AdGroupAgeReport adGroupAgeReport : adGroupAgeReports) {
                            if (adGroupAgeReport.AdGroupId.equals(adGroupReport.Id)) {
                                adGroupReport.AdGroupAges.add(adGroupAgeReport);
                            }
                        }

                        cr.AdGroups.add(adGroupReport);
                    }
                }

                // ExtensionLocations
                for (AdExtensionLocationReport adExtensionLocationReport : extensionLocations) {
                    if (adExtensionLocationReport.CampaignId.equals(campaignId)) {
                        cr.ExtensionLocations.add(adExtensionLocationReport);
                    }
                }

                // MobileExtensions
            /*for(AdExtensionMobileReport adExtensionMobileReport : mobileExtensions){
                if(adExtensionMobileReport.CampaignId.equals(campaignId)){
                    cr.MobileExtensions.add(adExtensionMobileReport);
                }
            }  */

                // SitelinksExtensions
           /* for(AdExtensionSitelinksReport adExtensionSitelinksReport : sitelinksExtensions){
                if(adExtensionSitelinksReport.CampaignId.equals(campaignId)){
                    cr.SitelinksExtensions.add(adExtensionSitelinksReport);
                }
            }    */

                // Languages
                for (LanguageReport languageReport : languages) {
                    if (languageReport.CampaignId.equals(campaignId)) {
                        cr.Languages.add(languageReport);
                    }
                }

                // Platforms
                for (PlatformReport platformReport : platforms) {
                    if (platformReport.CampaignId.equals(campaignId)) {
                        cr.Platforms.add(platformReport);
                    }
                }

                // Keywords
                for (KeywordReport keywordReport : campaignKeywords) {
                    if (keywordReport.CampaignId.equals(campaignId)) {
                        cr.Keywords.add(keywordReport);
                    }
                }

                // Proximities
                for (ProximityReport proximityReport : proximities) {
                    if (proximityReport.CampaignId.equals(campaignId)) {
                        cr.Proximities.add(proximityReport);
                    }
                }


                // Locations
                for (LocationReport locationReport : locations) {
                    if (locationReport.CampaignId.equals(campaignId)) {
                        cr.Locations.add(locationReport);
                    }
                }


            }

            try {

                String result = "";

                JAXBContext contextObj = JAXBContext.newInstance(GA_Report.class);

                Marshaller marshallerObj = contextObj.createMarshaller();
                marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

                StringWriter sw = new StringWriter();

                marshallerObj.marshal(report, sw);
                result = sw.getBuffer().toString();
                //System.out.println(result);

                FileWriter fw = new FileWriter(filePath + File.separator + accountId + ".xml");
                BufferedWriter bw = new BufferedWriter(fw);

                bw.write(result);
                bw.flush();
                bw.close();

            } catch (Exception exc) {
                exc.printStackTrace();
            }

    }


    protected ArrayList<SitelinksReport> GetFeedItemsSitelinksReportExc(String clientId) throws Exception{

        ArrayList<SitelinksReport> result = new ArrayList<SitelinksReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();
        FeedItemServiceInterface feedItemService = sf.GetFeedItemServiceInterface(clientId);


        ArrayList<CampaignFeedMapping> feedsByCampaign = GetFeedsByCampaignExc(clientId, "1");

        SitelinksReport sitelink = new SitelinksReport();
        sitelink.Sitelinks = feedsByCampaign;


        result.add(sitelink);





        return result;
    }

    protected ArrayList<AdExtensionLocationReport> GetAdExtensionLocationReportExc(String clientId) throws Exception{

        ArrayList<AdExtensionLocationReport> result = new ArrayList<AdExtensionLocationReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        CampaignAdExtensionServiceInterface adService = sf.GetCampaignAdExtensionService(clientId);

        int offset = 0;

        // Create selector.
        Selector selector = new Selector();
        selector.setFields(new String[]{
                "AdExtensionId",
                "Address",
                "ApprovalStatus",
                "CompanyName",
                "LocationExtensionSource",
                "PhoneNumber",
                "Status"
        });
        selector.setOrdering(new OrderBy[]{new OrderBy("AdExtensionId", SortOrder.ASCENDING)});
        selector.setPaging(new Paging(offset, PAGE_SIZE));

        Predicate predicate = new Predicate("Status", PredicateOperator.NOT_EQUALS, new String[] {"REMOVED"});
        Predicate[] predicates = new Predicate[] {predicate};
        selector.setPredicates(predicates);

        CampaignAdExtensionPage page = null;

        try {

            do {

                page = adService.get(selector);

                if (page.getEntries() != null && page.getEntries().length > 0) {
                    // Display results.
                    for (CampaignAdExtension campaignAdExtension : page.getEntries()) {

                        if (campaignAdExtension.getAdExtension().getAdExtensionType().equalsIgnoreCase("LocationExtension")) {
                            if (campaignAdExtension.getAdExtension() instanceof LocationExtension) {
                                LocationExtension locationExtension = (LocationExtension)campaignAdExtension.getAdExtension();
                                AdExtensionLocationReport adExtension = new AdExtensionLocationReport();

                                adExtension.AdExtensionId = locationExtension.getId();
                                adExtension.AddressLine1 = locationExtension.getAddress().getStreetAddress();
                                adExtension.AddressLine2 = locationExtension.getAddress().getStreetAddress2();
                                adExtension.CampaignId = campaignAdExtension.getCampaignId();
                                adExtension.CityName = locationExtension.getAddress().getCityName();
                                adExtension.CompanyName = locationExtension.getCompanyName();
                                adExtension.CountryCode = locationExtension.getAddress().getCountryCode();
                                adExtension.PhoneNumber = locationExtension.getPhoneNumber();
                                adExtension.PostalCode = locationExtension.getAddress().getPostalCode();
                                adExtension.ProvinceCode = locationExtension.getAddress().getProvinceCode();
                                adExtension.ProvinceName = locationExtension.getAddress().getProvinceName();

                                if (campaignAdExtension.getApprovalStatus() == CampaignAdExtensionApprovalStatus.APPROVED) {
                                    adExtension.ApprovalStatus = "A";
                                } else if (campaignAdExtension.getApprovalStatus() == CampaignAdExtensionApprovalStatus.DISAPPROVED) {
                                    adExtension.ApprovalStatus = "D";
                                } else if (campaignAdExtension.getApprovalStatus() == CampaignAdExtensionApprovalStatus.UNCHECKED) {
                                    adExtension.ApprovalStatus = "U";
                                }

                                if (locationExtension.getSource() == LocationExtensionSource.ADWORDS_FRONTEND) {
                                    adExtension.LocationExtensionSource = "AF";
                                } else if (locationExtension.getSource() == LocationExtensionSource.LBC_SYNC) {
                                    adExtension.LocationExtensionSource = "LS";
                                }

                                if (campaignAdExtension.getStatus() == CampaignAdExtensionStatus.ENABLED) {
                                    adExtension.Status = "A";
                                } else if (campaignAdExtension.getStatus() == CampaignAdExtensionStatus.REMOVED) {
                                    adExtension.Status = "D";
                                }

                                result.add(adExtension);
                            }
                        }

                    }
                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (Exception exc) {
            throw exc;
        }

        return result;
    }

    protected ArrayList<CampaignFeedMapping> GetFeedsByCampaignExc(String clientId, String placeHolderType) throws Exception{

        //ashMap<Long, ArrayList<Long>> campaignFeedsMapping = new HashMap<Long, ArrayList<Long>>();

        ArrayList<CampaignFeedMapping> feedMappings = new ArrayList<CampaignFeedMapping>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();
        CampaignFeedServiceInterface campaignFeedService = sf.GetCampaignFeedServiceInterface(clientId);


        int offset = 0;

        // Create selector.
        Selector selector = new Selector();
        selector.setFields(new String[]{
                "CampaignId",
                "FeedId",
                "MatchingFunction"
        });

        ArrayList<Long> validIds = GetFeedIds(clientId, placeHolderType);

        selector.setPaging(new Paging(offset, PAGE_SIZE));

        CampaignFeedPage page = null;


        try{
            do{
                page = campaignFeedService.get(selector);
                if (page.getEntries() != null && page.getEntries().length > 0) {

                    for (CampaignFeed cf : page.getEntries()){

                        if(validIds.contains(cf.getFeedId())){

                            CampaignFeedMapping cfm = new CampaignFeedMapping();

                            Function f = cf.getMatchingFunction();

                            FunctionOperator fOperator = f.getOperator();

                            FunctionArgumentOperand[] lOperands = f.getLhsOperand();
                            FunctionArgumentOperand[] rOperands = f.getRhsOperand();

                            if (fOperator.equals(FunctionOperator.IN) || fOperator.equals(FunctionOperator.EQUALS)){

                                RequestContextOperand rco = (RequestContextOperand)lOperands[0];

                                if (rco.getContextType().equals(RequestContextOperandContextType.FEED_ITEM_ID)){

                                    CampaignFeedMapping cfmAux = GetCampaignFeedMapping(feedMappings, cf.getCampaignId());

                                    if (cfmAux != null){

                                        CampaignFeedItemMapping cfim = new CampaignFeedItemMapping();

                                        cfim.FeedId = cf.getFeedId();

                                        for (FunctionArgumentOperand rOperand : rOperands){

                                            ConstantOperand co = (ConstantOperand)rOperand;

                                            if (co.getType().equals(ConstantOperandConstantType.LONG)){

                                                cfim.FeedItemIds.add(co.getLongValue());
                                            }

                                        }

                                        cfmAux.FeedMapping.add(cfim);
                                        cfm = cfmAux;

                                        feedMappings.add(cfm);

                                    }else{

                                        cfmAux = new CampaignFeedMapping();
                                        cfmAux.CampaignId = cf.getCampaignId();

                                        CampaignFeedItemMapping cfim = new CampaignFeedItemMapping();

                                        cfim.FeedId = cf.getFeedId();

                                        for (FunctionArgumentOperand rOperand : rOperands){

                                            ConstantOperand co = (ConstantOperand)rOperand;

                                            if (co.getType().equals(ConstantOperandConstantType.LONG)){

                                                cfim.FeedItemIds.add(co.getLongValue());
                                            }

                                        }

                                        cfmAux.FeedMapping.add(cfim);
                                        cfm = cfmAux;
                                        feedMappings.add(cfm);
                                    }
                                }
                            }
                        }
                    }



                }
                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);
            } while (offset < page.getTotalNumEntries());
        }catch (Exception exc) {
            throw exc;
        }


        return feedMappings;


    }

    protected ArrayList<GA_CampaignStats> GetCampaignStatsExc(String clientId)  throws Exception{

        ArrayList<GA_CampaignStats> result = new ArrayList<GA_CampaignStats>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get campaign service
        CampaignServiceInterface campaignService = sf.GetCampaignService(clientId);

        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));

        selector.setFields(new String[]
                {
                        "AdServingOptimizationStatus",
                        "BidCeiling",
                        "BiddingStrategyType",
                        "BidType",
                        "BudgetId",
                        "EndDate",
                        "EnhancedCpcEnabled",
                        "FrequencyCapMaxImpressions",
                        "Id",
                        "Level",
                        "Name",
                        "PricingMode",
                        "StartDate",
                        "Status",
                        "Settings",
                        "TargetContentNetwork",
                        "TargetGoogleSearch",
                        "TargetPartnerSearchNetwork",
                        "TargetSearchNetwork",
                        "TimeUnit",
                });

        Predicate predicate = new Predicate("Status", PredicateOperator.NOT_EQUALS, new String[] {"REMOVED"});
        Predicate[] predicates = new Predicate[] {predicate};
        selector.setPredicates(predicates);


        CampaignPage page = null;

        try {

            do {

                page = campaignService.get(selector);

                if (page.getEntries() != null) {

                    for (Campaign campaign : page.getEntries()) {

                        GA_CampaignStats stat = new GA_CampaignStats();

                        if (campaign.getAdServingOptimizationStatus() == AdServingOptimizationStatus.OPTIMIZE) {
                            stat.AdServingOptimizationStatus = "O";
                        } else if (campaign.getAdServingOptimizationStatus() == AdServingOptimizationStatus.CONVERSION_OPTIMIZE) {
                            stat.AdServingOptimizationStatus = "C";
                        } else if (campaign.getAdServingOptimizationStatus() == AdServingOptimizationStatus.ROTATE) {
                            stat.AdServingOptimizationStatus = "R";
                        } else if (campaign.getAdServingOptimizationStatus() == AdServingOptimizationStatus.ROTATE_INDEFINITELY) {
                            stat.AdServingOptimizationStatus = "RI";
                        } else if (campaign.getAdServingOptimizationStatus() == AdServingOptimizationStatus.UNAVAILABLE) {
                            stat.AdServingOptimizationStatus = "U";
                        }

                        if (campaign.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.BUDGET_OPTIMIZER) {
                            stat.BiddingStrategyType = "BO";
                        } else if (campaign.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.CONVERSION_OPTIMIZER) {
                            stat.BiddingStrategyType = "CO";
                        } else if (campaign.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPC) {
                            stat.BiddingStrategyType = "MCPC";
                        } else if (campaign.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPM) {
                            stat.BiddingStrategyType = "MCPM";
                        } else if (campaign.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.PERCENT_CPA) {
                            stat.BiddingStrategyType = "PCPA";
                        }

                        stat.BudgetId = campaign.getBudget().getBudgetId();
                        stat.EndDate = campaign.getEndDate();
                        stat.Id = campaign.getId();
                        stat.Name = campaign.getName();
                        stat.StartDate = campaign.getStartDate();

                        if (campaign.getStatus() == CampaignStatus.ENABLED) {
                            stat.Status = "A";
                        } else if (campaign.getStatus() == CampaignStatus.REMOVED) {
                            stat.Status = "D";
                        } else if (campaign.getStatus() == CampaignStatus.PAUSED) {
                            stat.Status = "P";
                        }

                        stat.TargetContentNetwork = campaign.getNetworkSetting().getTargetContentNetwork();
                        stat.TargetGoogleSearch = campaign.getNetworkSetting().getTargetGoogleSearch();
                        stat.TargetPartnerSearchNetwork = campaign.getNetworkSetting().getTargetPartnerSearchNetwork();
                        stat.TargetSearchNetwork = campaign.getNetworkSetting().getTargetSearchNetwork();

                        if (campaign.getFrequencyCap() != null) {
                            stat.FrequencyCapMaxImpressions = campaign.getFrequencyCap().getImpressions();
                            if (campaign.getFrequencyCap().getLevel() == Level.CREATIVE) {
                                stat.Level = "C";
                            } else if (campaign.getFrequencyCap().getLevel() == Level.ADGROUP) {
                                stat.Level = "A";
                            } else if (campaign.getFrequencyCap().getLevel() == Level.CAMPAIGN) {
                                stat.Level = "CM";
                            } else if (campaign.getFrequencyCap().getLevel() == Level.UNKNOWN) {
                                stat.Level = "U";
                            }

                            if (campaign.getFrequencyCap().getTimeUnit() == TimeUnit.MINUTE) {
                                stat.TimeUnit = "M";
                            } else if (campaign.getFrequencyCap().getTimeUnit() == TimeUnit.HOUR) {
                                stat.TimeUnit = "H";
                            } else if (campaign.getFrequencyCap().getTimeUnit() == TimeUnit.DAY) {
                                stat.TimeUnit = "D";
                            } else if (campaign.getFrequencyCap().getTimeUnit() == TimeUnit.WEEK) {
                                stat.TimeUnit = "W";
                            } else if (campaign.getFrequencyCap().getTimeUnit() == TimeUnit.MONTH) {
                                stat.TimeUnit = "MN";
                            } else if (campaign.getFrequencyCap().getTimeUnit() == TimeUnit.LIFETIME) {
                                stat.TimeUnit = "L";
                            }
                        }

                        BiddingScheme bs = campaign.getBiddingStrategyConfiguration().getBiddingScheme();
                        if (bs instanceof BudgetOptimizerBiddingScheme) {
                            if (((BudgetOptimizerBiddingScheme)campaign.getBiddingStrategyConfiguration().getBiddingScheme()).getBidCeiling() != null) {
                                stat.BidCeiling = (double)((BudgetOptimizerBiddingScheme)campaign.getBiddingStrategyConfiguration().getBiddingScheme()).getBidCeiling().getMicroAmount() / (double)1000000;
                            }
                            stat.EnhancedCpcEnabled = ((BudgetOptimizerBiddingScheme)campaign.getBiddingStrategyConfiguration().getBiddingScheme()).getEnhancedCpcEnabled();
                        } else if (bs instanceof ConversionOptimizerBiddingScheme) {
                            if (((ConversionOptimizerBiddingScheme)campaign.getBiddingStrategyConfiguration().getBiddingScheme()).getBidType() == ConversionOptimizerBiddingSchemeBidType.TARGET_CPA) {
                                stat.BidType = "T";
                            } /*else if (((ConversionOptimizerBiddingScheme)campaign.getBiddingStrategyConfiguration().getBiddingScheme()).getBidType() == ConversionOptimizerBiddingSchemeBidType.MAX_CPA) {
                                stat.BidType = "M";
                            }   */

                            if (((ConversionOptimizerBiddingScheme)campaign.getBiddingStrategyConfiguration().getBiddingScheme()).getPricingMode() == ConversionOptimizerBiddingSchemePricingMode.CLICKS) {
                                stat.PricingMode = "C";
                            } else if (((ConversionOptimizerBiddingScheme)campaign.getBiddingStrategyConfiguration().getBiddingScheme()).getPricingMode() == ConversionOptimizerBiddingSchemePricingMode.CONVERSIONS) {
                                stat.PricingMode = "CN";
                            }
                        } else if (bs instanceof ManualCpcBiddingScheme) {
                            stat.EnhancedCpcEnabled = ((ManualCpcBiddingScheme)campaign.getBiddingStrategyConfiguration().getBiddingScheme()).getEnhancedCpcEnabled();
                        }

                        for (Setting setting : campaign.getSettings()) {
                            if (setting instanceof GeoTargetTypeSetting) {
                                if (((GeoTargetTypeSetting)setting).getNegativeGeoTargetType() == GeoTargetTypeSettingNegativeGeoTargetType.DONT_CARE) {
                                    stat.GeoTargetNegativeType = "D";
                                } else if (((GeoTargetTypeSetting)setting).getNegativeGeoTargetType() == GeoTargetTypeSettingNegativeGeoTargetType.LOCATION_OF_PRESENCE) {
                                    stat.GeoTargetNegativeType = "L";
                                }

                                if (((GeoTargetTypeSetting)setting).getPositiveGeoTargetType() == GeoTargetTypeSettingPositiveGeoTargetType.DONT_CARE) {
                                    stat.GeoTargetPositiveType = "D";
                                } else if (((GeoTargetTypeSetting)setting).getPositiveGeoTargetType() == GeoTargetTypeSettingPositiveGeoTargetType.AREA_OF_INTEREST) {
                                    stat.GeoTargetPositiveType = "A";
                                } else if (((GeoTargetTypeSetting)setting).getPositiveGeoTargetType() == GeoTargetTypeSettingPositiveGeoTargetType.LOCATION_OF_PRESENCE) {
                                    stat.GeoTargetPositiveType = "L";
                                }
                            } else if (setting instanceof KeywordMatchSetting) {
                                stat.KeywordMatch = ((KeywordMatchSetting)setting).getOptIn();
                            } else if (setting instanceof RealTimeBiddingSetting) {
                                stat.KeywordMatch = ((RealTimeBiddingSetting)setting).getOptIn();
                            }
                        }
                        result.add(stat);
                    }
                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (RemoteException e) {
            throw e;
        }


        return result;
    }

    protected ArrayList<BudgetReport> GetBudgetStatsExc(String clientId) throws Exception{
        ArrayList<BudgetReport> result = new ArrayList<BudgetReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get budget service
        BudgetServiceInterface budgetService = sf.GetBudgetService(clientId);

        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));

        selector.setFields(new String[] {
                "Amount",
                "BudgetId",
                "BudgetName",
                "BudgetStatus",
                "DeliveryMethod",
                "IsBudgetExplicitlyShared",
                "Period"
        });

        Predicate predicate = new Predicate("BudgetStatus", PredicateOperator.NOT_EQUALS, new String[] {"REMOVED"});
        Predicate[] predicates = new Predicate[] {predicate};
        selector.setPredicates(predicates);

        BudgetPage page = null;

        try {
            do {
                page = budgetService.get(selector);
                if (page.getEntries() != null) {
                    for (Budget budget : page.getEntries()) {
                        BudgetReport budgetReport = new BudgetReport();

                        budgetReport.Amount = (double)budget.getAmount().getMicroAmount() / (double)1000000;
                        budgetReport.BudgetId = budget.getBudgetId();
                        budgetReport.BudgetName = budget.getName();
                        budgetReport.IsBudgetExplicitlyShared = budget.getIsExplicitlyShared();

                        if (budget.getStatus() == BudgetBudgetStatus.ENABLED) {
                            budgetReport.BudgetStatus = "A";
                        } else if (budget.getStatus() == BudgetBudgetStatus.REMOVED) {
                            budgetReport.BudgetStatus = "D";
                        } else if (budget.getStatus() == BudgetBudgetStatus.UNKNOWN) {
                            budgetReport.BudgetStatus = "U";
                        }

                        if (budget.getDeliveryMethod() == BudgetBudgetDeliveryMethod.ACCELERATED) {
                            budgetReport.DeliveryMethod = "A";
                        } else if (budget.getDeliveryMethod() == BudgetBudgetDeliveryMethod.STANDARD) {
                            budgetReport.DeliveryMethod = "S";
                        }

                        if (budget.getPeriod() == BudgetBudgetPeriod.DAILY) {
                            budgetReport.Period = "D";
                        }

                        result.add(budgetReport);
                    }
                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (RemoteException e) {
            throw e;
        }


        return result;
    }

    protected ArrayList<LocationExtensionReport> GetFeedItemsLocationExtensionReportExc(String clientId) throws Exception{

        ArrayList<LocationExtensionReport> result = new ArrayList<LocationExtensionReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();
        FeedItemServiceInterface feedItemService = sf.GetFeedItemServiceInterface(clientId);


        ArrayList<CampaignFeedMapping> feedsByCampaign = GetFeedsByCampaignExc(clientId, "7");

        LocationExtensionReport sitelink = new LocationExtensionReport();
        sitelink.LocationExtensions = feedsByCampaign;


        result.add(sitelink);

        return result;
    }

    protected ArrayList<PlatformReport> GetCampaignDevicesExc(String clientId) throws Exception{

        ArrayList<PlatformReport> result = new ArrayList<PlatformReport>();


        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get Campaign Criterion Service
        CampaignCriterionServiceInterface campaignCriterionService = sf.GetCampaignCriterionService(clientId);


        int offset = 0;

        // Create selector.
        Selector selector = new Selector();
        selector.setFields(new String[]{
                "BidModifier",
                "Id",
                "PlatformName"
        });
        //selector.setOrdering(new OrderBy[] {new OrderBy("Name", SortOrder.ASCENDING)});
        Predicate platformPredicate = new Predicate("CriteriaType", PredicateOperator.IN, new String[]{"PLATFORM"});
        selector.setPaging(new Paging(offset, PAGE_SIZE));

        // Create predicates.
        /*Predicate campaignIdPredicate =
                new Predicate("CampaignId", PredicateOperator.IN, campaignIds);*/
        selector.setPredicates(new Predicate[]{platformPredicate});

        CampaignCriterionPage page = null;

        try {

            do {
                page = campaignCriterionService.get(selector);

                if (page.getEntries() != null) {

                    for (CampaignCriterion campaignCriterion : page.getEntries()) {
                        if (campaignCriterion.getCriterion() instanceof Platform) {
                            Platform platform = (Platform)campaignCriterion.getCriterion();
                            PlatformReport platformReport = new PlatformReport();

                            platformReport.BidMultiplier = campaignCriterion.getBidModifier();
                            platformReport.CampaignId = campaignCriterion.getCampaignId();
                            platformReport.Id = platform.getId();
                            platformReport.Name = platform.getPlatformName();

                            result.add(platformReport);
                        }
                    }
                }

                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (Exception exc) {
            throw exc;
        }

        return result;

    }

    protected ArrayList<LanguageReport> GetCampaignLanguagesExc(String clientId) throws Exception{

        ArrayList<LanguageReport> result = new ArrayList<LanguageReport>();


        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get Campaign Criterion Service
        CampaignCriterionServiceInterface campaignCriterionService = sf.GetCampaignCriterionService(clientId);


        int offset = 0;

        // Create selector.
        Selector selector = new Selector();
        selector.setFields(new String[]{
                "Id",
                "LanguageName"
        });
        //selector.setOrdering(new OrderBy[] {new OrderBy("Name", SortOrder.ASCENDING)});
        Predicate languagePredicate = new Predicate("CriteriaType", PredicateOperator.IN, new String[]{"LANGUAGE"});

        selector.setPaging(new Paging(offset, PAGE_SIZE));

        // Create predicates.
        /*Predicate campaignIdPredicate =
                new Predicate("CampaignId", PredicateOperator.IN, campaignIds);*/
        selector.setPredicates(new Predicate[]{languagePredicate});

        CampaignCriterionPage page = null;

        try {

            do {
                page = campaignCriterionService.get(selector);

                if (page.getEntries() != null) {

                    for (CampaignCriterion campaignCriterion : page.getEntries()) {
                        if (campaignCriterion.getCriterion() instanceof Language) {
                            LanguageReport languageReport = new LanguageReport();
                            languageReport.CampaignId = campaignCriterion.getCampaignId();
                            languageReport.Id = ((Language) campaignCriterion.getCriterion()).getId();
                            languageReport.Name = ((Language) campaignCriterion.getCriterion()).getName();

                            result.add(languageReport);
                        }
                    }
                }

                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (Exception exc) {
            throw exc;
        }

        return result;

    }

    protected ArrayList<KeywordReport> GetKeywordsExc(String clientId) throws Exception{

        ArrayList<KeywordReport> result = new ArrayList<KeywordReport>();


        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get Campaign Criterion Service
        CampaignCriterionServiceInterface campaignCriterionService = sf.GetCampaignCriterionService(clientId);


        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));
        //selector.setOrdering(new OrderBy[] {new OrderBy("Name", SortOrder.ASCENDING)});

        selector.setFields(new String[]{
                "Id",
                "KeywordMatchType",
                "KeywordText"
        });

        CampaignCriterionPage page = null;

        try {

            do {

                page = campaignCriterionService.get(selector);

                if (page.getEntries() != null) {

                    for (CampaignCriterion campaignCriterion : page.getEntries()) {


                        if (campaignCriterion.getCampaignCriterionType().equalsIgnoreCase("NegativeCampaignCriterion")) {
                            if (campaignCriterion instanceof NegativeCampaignCriterion) {
                                NegativeCampaignCriterion ncc = (NegativeCampaignCriterion) campaignCriterion;
                                if (ncc.getCriterion() instanceof Keyword) {
                                    KeywordReport keywordReport = new KeywordReport();

                                    Keyword keyword = (Keyword) ncc.getCriterion();

                                    keywordReport.CampaignId = campaignCriterion.getCampaignId();
                                    keywordReport.Id = keyword.getId();
                                    keywordReport.KeywordText = keyword.getText();

                                    if (keyword.getMatchType() == KeywordMatchType.EXACT) {
                                        keywordReport.KeywordMatchType = "E";
                                    } else if (keyword.getMatchType() == KeywordMatchType.PHRASE) {
                                        keywordReport.KeywordMatchType = "P";
                                    } else if (keyword.getMatchType() == KeywordMatchType.BROAD) {
                                        keywordReport.KeywordMatchType = "B";
                                    }

                                    result.add(keywordReport);
                                }
                            }
                        }


                    }


                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (Exception exc) {
            throw exc;
        }


        return result;


    }

    protected ArrayList<ProximityReport> GetProximitiesExc(String clientId) throws Exception{
        ArrayList<ProximityReport> result = new ArrayList<ProximityReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get Campaign Criterion Service
        CampaignCriterionServiceInterface campaignCriterionService = sf.GetCampaignCriterionService(clientId);

        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));
        //selector.setOrdering(new OrderBy[] {new OrderBy("Name", SortOrder.ASCENDING)});

        selector.setFields(new String[]{
                "Address",
                "GeoPoint",
                "Id",
                "RadiusDistanceUnits",
                "RadiusInUnits"
        });

        // Create predicates.
        Predicate criterionTypePredicate =
                new Predicate("CriteriaType", PredicateOperator.EQUALS, new String[]{"PROXIMITY"});
        selector.setPredicates(new Predicate[]{criterionTypePredicate});

        CampaignCriterionPage page = null;

        try {
            do {
                page = campaignCriterionService.get(selector);
                if (page.getEntries() != null) {
                    for (CampaignCriterion campaignCriterion : page.getEntries()) {
                        if (campaignCriterion.getCriterion().getCriterionType().equalsIgnoreCase(CriterionType.PROXIMITY.toString())) {
                            if (campaignCriterion.getCriterion() instanceof Proximity) {
                                ProximityReport proximityReport = new ProximityReport();

                                Proximity proximity = (Proximity) campaignCriterion.getCriterion();

                                if (proximity.getAddress() != null) {
                                    proximityReport.AddressLine1 = proximity.getAddress().getStreetAddress();
                                    proximityReport.AddressLine2 = proximity.getAddress().getStreetAddress2();
                                    proximityReport.CampaignId = campaignCriterion.getCampaignId();
                                    proximityReport.CityName = proximity.getAddress().getCityName();
                                    proximityReport.CountryCode = proximity.getAddress().getCountryCode();
                                    proximityReport.PostalCode = proximity.getAddress().getPostalCode();
                                    proximityReport.ProvinceCode = proximity.getAddress().getProvinceCode();
                                    proximityReport.ProvinceName = proximity.getAddress().getProvinceName();
                                }

                                if (proximity.getGeoPoint() != null) {
                                    proximityReport.Latitude = proximity.getGeoPoint().getLatitudeInMicroDegrees();
                                    proximityReport.Longitude = proximity.getGeoPoint().getLongitudeInMicroDegrees();
                                }

                                proximityReport.CampaignId = campaignCriterion.getCampaignId();
                                proximityReport.Id = proximity.getId();
                                proximityReport.Radius = proximity.getRadiusInUnits();

                                result.add(proximityReport);
                            }
                        }
                    }
                }

                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (Exception exc) {
            throw exc;
        }

        return result;
    }

    protected ArrayList<AdGroupReport> GetAdGroupStatsExc(String clientId) throws Exception{

        ArrayList<AdGroupReport> result = new ArrayList<AdGroupReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get AdGroup Service
        AdGroupServiceInterface adGroupService = sf.GetAdGroupService(clientId);

        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));
        selector.setOrdering(new OrderBy[]{new OrderBy("Name", SortOrder.ASCENDING)});

        selector.setFields(new String[]{
                "BiddingStrategyType",
                "CampaignId",
                // "ContentBid",
                "CpcBid",
                "CpmBid",
                "Id",
                "Name",
                "PercentCpaBid",
                "Settings",
                "Status",
                "TargetCpaBid"
        });

        Predicate predicate = new Predicate("Status", PredicateOperator.NOT_EQUALS, new String[] {"REMOVED"});
        Predicate[] predicates = new Predicate[] {predicate};
        selector.setPredicates(predicates);

        AdGroupPage page = null;

        try {

            do {

                page = adGroupService.get(selector);

                if (page.getEntries() != null) {
                    for (AdGroup adGroup : page.getEntries()) {
                        AdGroupReport adGroupReport = new AdGroupReport();

                        if (adGroup.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.BUDGET_OPTIMIZER) {
                            adGroupReport.BiddingStrategyType = "BO";
                        } else if (adGroup.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.CONVERSION_OPTIMIZER) {
                            adGroupReport.BiddingStrategyType = "CO";
                        } else if (adGroup.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPC) {
                            adGroupReport.BiddingStrategyType = "MCPC";
                        } else if (adGroup.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPM) {
                            adGroupReport.BiddingStrategyType = "MCPM";
                        } else if (adGroup.getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.PERCENT_CPA) {
                            adGroupReport.BiddingStrategyType = "PCPA";
                        }

                        adGroupReport.CampaignId = adGroup.getCampaignId();
                        adGroupReport.Id = adGroup.getId();
                        adGroupReport.Name = adGroup.getName();

                        if (adGroup.getStatus() == AdGroupStatus.ENABLED) {
                            adGroupReport.Status = "E";
                        } else if (adGroup.getStatus() == AdGroupStatus.REMOVED) {
                            adGroupReport.Status = "D";
                        } else if (adGroup.getStatus() == AdGroupStatus.PAUSED) {
                            adGroupReport.Status = "P";
                        }

                        for (Bids bid : adGroup.getBiddingStrategyConfiguration().getBids()) {
                            if (bid instanceof CpcBid) {
                                if (((CpcBid)bid).getBid() != null) {
                                    adGroupReport.ContentBid = (double)((CpcBid)bid).getBid().getMicroAmount() / (double)1000000;
                                }
                                if (((CpcBid)bid).getBid() != null) {
                                    adGroupReport.CpcBid = (double)((CpcBid)bid).getBid().getMicroAmount() / (double)1000000;
                                }
                            } else if (bid instanceof CpmBid) {
                                if (((CpmBid)bid).getBid() != null) {
                                    adGroupReport.CpmBid = (double)((CpmBid)bid).getBid().getMicroAmount() / (double)1000000;
                                }
                            } else if (bid instanceof PercentCpaBid) {
                                adGroupReport.PercentCpaBid = ((PercentCpaBid)bid).getBid();
                            } else if (bid instanceof CpaBid) {
                                if (((CpaBid)bid).getBid() != null) {
                                    adGroupReport.TargetCpaBid = (double)((CpaBid)bid).getBid().getMicroAmount() / (double)1000000;
                                }
                            }
                        }

                        if (adGroup.getSettings() != null) {
                            for (Setting setting : adGroup.getSettings()) {
                                if (setting instanceof TargetingSetting) {
                                    TargetingSettingDetail[] details = ((TargetingSetting)setting).getDetails();
                                    if (details != null) {
                                        adGroupReport.Details = new GA_TargetingSettingDetail[details.length];
                                        for (int i=0; i<details.length; i++) {
                                            adGroupReport.Details[i] = new GA_TargetingSettingDetail();

                                            if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.USER_INTEREST_AND_LIST) {
                                                adGroupReport.Details[i].CriterionTypeGroup = "UI";
                                            } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.VERTICAL) {
                                                adGroupReport.Details[i].CriterionTypeGroup = "V";
                                            } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.GENDER) {
                                                adGroupReport.Details[i].CriterionTypeGroup = "G";
                                            } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.AGE_RANGE) {
                                                adGroupReport.Details[i].CriterionTypeGroup = "A";
                                            } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.PLACEMENT) {
                                                adGroupReport.Details[i].CriterionTypeGroup = "P";
                                            } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.UNKNOWN) {
                                                adGroupReport.Details[i].CriterionTypeGroup = "UN";
                                            } else if (details[i].getCriterionTypeGroup() == CriterionTypeGroup.KEYWORD) {
                                                adGroupReport.Details[i].CriterionTypeGroup = "K";
                                            }

                                            adGroupReport.Details[i].TargetAll = details[i].getTargetAll();
                                        }
                                    }
                                }
                            }
                        }


                        result.add(adGroupReport);

                    }
                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());

        } catch (RemoteException ex) {
            throw ex;
        }

        return result;

    }

    protected ArrayList<TextAdReport> GetTextAdsExc(String clientId) throws Exception{

        ArrayList<TextAdReport> result = new ArrayList<TextAdReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        AdGroupAdServiceInterface adService = sf.GetAdGroupAdService(clientId);

        int offset = 0;

        // Create selector.
        Selector selector = new Selector();
        selector.setFields(new String[]{
                "Description1",
                "Description2",
                "DisplayUrl",
                "Headline",
                "Id",
                "Status",
                "Url"
        });
        selector.setOrdering(new OrderBy[]{new OrderBy("Id", SortOrder.ASCENDING)});
        selector.setPaging(new Paging(offset, PAGE_SIZE));

        // Create predicates.
        /*Predicate adGroupIdPredicate =
                new Predicate("AdGroupId", PredicateOperator.IN, new String[]{adGroupId.toString()});*/
        // By default disabled ads aren't returned by the selector. To return them
        // include the DISABLED status in a predicate.
        Predicate statusPredicate =
                new Predicate("Status", PredicateOperator.NOT_EQUALS,
                        new String[]{"DISABLED"});
        Predicate adTypePredicate =
                new Predicate("AdType", PredicateOperator.EQUALS, new String[]{"TEXT_AD"});
        selector.setPredicates(new Predicate[]{statusPredicate, adTypePredicate});
        AdGroupAdPage page = null;

        try {

            do {

                page = adService.get(selector);

                if (page.getEntries() != null) {
                    for (AdGroupAd adGroupAd : page.getEntries()) {
                        TextAdReport textAdReport = new TextAdReport();
                        if (adGroupAd.getAd() instanceof TextAd) {
                            TextAd textAd = (TextAd)adGroupAd.getAd();

                            textAdReport.AdGroupId = adGroupAd.getAdGroupId();
                            textAdReport.Description1 = textAd.getDescription1();
                            textAdReport.Description2 = textAd.getDescription2();
                            textAdReport.DisplayUrl = textAd.getDisplayUrl();
                            textAdReport.Headline = textAd.getHeadline();
                            textAdReport.Id = textAd.getId();
                            textAdReport.Url = textAd.getUrl();

                            if (adGroupAd.getStatus() == AdGroupAdStatus.ENABLED) {
                                textAdReport.Status = "E";
                            } else if (adGroupAd.getStatus() == AdGroupAdStatus.PAUSED) {
                                textAdReport.Status = "P";
                            } else if (adGroupAd.getStatus() == AdGroupAdStatus.DISABLED) {
                                textAdReport.Status = "D";
                            }

                            result.add(textAdReport);
                        }

                        /*System.out.println("Ad with id  \"" + adGroupAd.getAd().getId() + "\"" + " and type \""
                                + adGroupAd.getAd().getAdType() + "\" was found."); */
                    }
                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());
        } catch (Exception exc) {
            throw exc;
        }


        return result;

    }

    protected ArrayList<ImageAdReport> GetImageAdsExc(String clientId) throws Exception{

        ArrayList<ImageAdReport> result = new ArrayList<ImageAdReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        AdGroupAdServiceInterface adService = sf.GetAdGroupAdService(clientId);

        int offset = 0;

        // Create selector.
        Selector selector = new Selector();
        selector.setFields(new String[]{
                "DisplayUrl",
                "Id",
                "ImageCreativeName",
                "Status",
                "Url"
        });
        selector.setOrdering(new OrderBy[]{new OrderBy("Id", SortOrder.ASCENDING)});
        selector.setPaging(new Paging(offset, PAGE_SIZE));

        // Create predicates.
        /*Predicate adGroupIdPredicate =
                new Predicate("AdGroupId", PredicateOperator.IN, new String[]{adGroupId.toString()});*/
        // By default disabled ads aren't returned by the selector. To return them
        // include the DISABLED status in a predicate.
        Predicate statusPredicate =
                new Predicate("Status", PredicateOperator.NOT_EQUALS, new String[]{"DISABLED"});
        Predicate adTypePredicate =
                new Predicate("AdType", PredicateOperator.EQUALS, new String[]{"IMAGE_AD"});
        selector.setPredicates(new Predicate[]{statusPredicate, adTypePredicate});
        AdGroupAdPage page = null;

        try {

            do {

                page = adService.get(selector);

                if (page.getEntries() != null) {
                    for (AdGroupAd adGroupAd : page.getEntries()) {
                        ImageAdReport imageAdReport = new ImageAdReport();
                        if (adGroupAd.getAd() instanceof ImageAd) {
                            ImageAd imageAd = (ImageAd)adGroupAd.getAd();

                            imageAdReport.AdGroupId = adGroupAd.getAdGroupId();
                            imageAdReport.DisplayUrl = imageAd.getDisplayUrl();
                            imageAdReport.Name = imageAd.getName();
                            imageAdReport.Id = imageAd.getId();
                            imageAdReport.Url = imageAd.getUrl();

                            if (adGroupAd.getStatus() == AdGroupAdStatus.ENABLED) {
                                imageAdReport.Status = "E";
                            } else if (adGroupAd.getStatus() == AdGroupAdStatus.PAUSED) {
                                imageAdReport.Status = "P";
                            } else if (adGroupAd.getStatus() == AdGroupAdStatus.DISABLED) {
                                imageAdReport.Status = "D";
                            }

                            result.add(imageAdReport);
                        }

                        /*System.out.println("Ad with id  \"" + adGroupAd.getAd().getId() + "\"" + " and type \""
                  + adGroupAd.getAd().getAdType() + "\" was found."); */
                    }
                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());
        } catch (Exception exc) {
            throw exc;
        }


        return result;

    }

    protected ArrayList<AdGroupKeywordReport> GetAdGroupKeywordsExc(String clientId) throws Exception{


        ArrayList<AdGroupKeywordReport> result = new ArrayList<AdGroupKeywordReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get AdGroup Service
        AdGroupCriterionServiceInterface adGroupCriterionService = sf.GetAdGroupCriterionService(clientId);

        int offset = 0;

        // Create selector.
        Selector selector = new Selector();
        selector.setFields(new String[]{
                "BiddingStrategyType",
                "CpcBid",
                "CpmBid",
                "CriterionUse",
                "DestinationUrl",
                "Id",
                "KeywordMatchType",
                "KeywordText",
                "PercentCpaBid",
                "Status"
        });
        selector.setOrdering(new OrderBy[]{new OrderBy("AdGroupId", SortOrder.ASCENDING)});
        selector.setPaging(new Paging(offset, PAGE_SIZE));

        // Create predicates.
        /*Predicate adGroupIdPredicate =
                new Predicate("AdGroupId", PredicateOperator.IN, new String[]{adGroupId.toString()});*/
        Predicate criteriaTypePredicate =
                new Predicate("CriteriaType", PredicateOperator.EQUALS, new String[]{"KEYWORD"});
        Predicate statusPredicate = new Predicate("Status", PredicateOperator.NOT_EQUALS, new String[] {"REMOVED"});
        selector.setPredicates(new Predicate[]{criteriaTypePredicate, statusPredicate});

        AdGroupCriterionPage page = null;
        try {

            do {

                page = adGroupCriterionService.get(selector);

                if (page.getEntries() != null && page.getEntries().length > 0) {
                    // Display results.
                    for (AdGroupCriterion adGroupCriterionResult : page.getEntries()) {

                        AdGroupKeywordReport adGroupKeyword = new AdGroupKeywordReport();

                        if (adGroupCriterionResult.getCriterion() instanceof Keyword) {
                            Keyword keyword = (Keyword)adGroupCriterionResult.getCriterion();

                            adGroupKeyword.AdGroupId = adGroupCriterionResult.getAdGroupId();
                            if (adGroupCriterionResult instanceof BiddableAdGroupCriterion) {
                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.BUDGET_OPTIMIZER) {
                                    adGroupKeyword.BiddingStrategyType = "BO";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.CONVERSION_OPTIMIZER) {
                                    adGroupKeyword.BiddingStrategyType = "CO";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPC) {
                                    adGroupKeyword.BiddingStrategyType = "MCPC";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPM) {
                                    adGroupKeyword.BiddingStrategyType = "MCPM";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.PERCENT_CPA) {
                                    adGroupKeyword.BiddingStrategyType = "PCPA";
                                }

                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBids() != null) {
                                    for (Bids bid : ((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBids()) {
                                        if (bid instanceof CpcBid) {
                                            if (((CpcBid)bid).getBid() != null) {
                                                adGroupKeyword.CpcBid = (double)((CpcBid)bid).getBid().getMicroAmount() / (double)1000000;
                                            }
                                        } else if (bid instanceof CpmBid) {
                                            if (((CpmBid)bid).getBid() != null) {
                                                adGroupKeyword.CpmBid = (double)((CpmBid)bid).getBid().getMicroAmount() / (double)1000000;
                                            }
                                        } else if (bid instanceof PercentCpaBid) {
                                            adGroupKeyword.PercentCpaBid = ((PercentCpaBid)bid).getBid();
                                        }
                                    }
                                }

                                adGroupKeyword.DestinationUrl = ((BiddableAdGroupCriterion)adGroupCriterionResult).getDestinationUrl();

                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.ENABLED) {
                                    adGroupKeyword.Status = "A";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.PAUSED) {
                                    adGroupKeyword.Status = "P";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.REMOVED) {
                                    adGroupKeyword.Status = "D";
                                }
                            }

                            if (adGroupCriterionResult.getCriterionUse() == CriterionUse.BIDDABLE) {
                                adGroupKeyword.CriterionUse = "B";
                            } else if (adGroupCriterionResult.getCriterionUse() == CriterionUse.NEGATIVE) {
                                adGroupKeyword.CriterionUse = "N";
                            }

                            adGroupKeyword.Id = adGroupCriterionResult.getCriterion().getId();

                            if (keyword.getMatchType() == KeywordMatchType.EXACT) {
                                adGroupKeyword.KeywordMatchType = "E";
                            } else if (keyword.getMatchType() == KeywordMatchType.PHRASE) {
                                adGroupKeyword.KeywordMatchType = "P";
                            } else if (keyword.getMatchType() == KeywordMatchType.BROAD) {
                                adGroupKeyword.KeywordMatchType = "B";
                            }

                            adGroupKeyword.KeywordText = keyword.getText();

                            result.add(adGroupKeyword);
                        }
                    }
                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (Exception exc) {
            exc.printStackTrace();
            throw exc;
        }

        return result;
    }

    protected ArrayList<AdGroupPlacementReport> GetAdGroupPlacementsExc(String clientId) throws Exception{


        ArrayList<AdGroupPlacementReport> result = new ArrayList<AdGroupPlacementReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get AdGroup Service
        AdGroupCriterionServiceInterface adGroupCriterionService = sf.GetAdGroupCriterionService(clientId);

        int offset = 0;

        // Create selector.
        Selector selector = new Selector();
        selector.setFields(new String[]{
                "BiddingStrategyType",
                "CpcBid",
                "CpmBid",
                "CriterionUse",
                "DestinationUrl",
                "Id",
                "PlacementUrl",
                "PercentCpaBid",
                "Status"
        });
        selector.setOrdering(new OrderBy[]{new OrderBy("AdGroupId", SortOrder.ASCENDING)});
        selector.setPaging(new Paging(offset, PAGE_SIZE));

        // Create predicates.
        /*Predicate adGroupIdPredicate =
                new Predicate("AdGroupId", PredicateOperator.IN, new String[]{adGroupId.toString()});*/
        Predicate criteriaTypePredicate =
                new Predicate("CriteriaType", PredicateOperator.EQUALS, new String[]{"PLACEMENT"});
        selector.setPredicates(new Predicate[]{criteriaTypePredicate});

        AdGroupCriterionPage page = null;
        try {

            do {

                page = adGroupCriterionService.get(selector);

                if (page.getEntries() != null && page.getEntries().length > 0) {
                    // Display results.
                    for (AdGroupCriterion adGroupCriterionResult : page.getEntries()) {

                        AdGroupPlacementReport adGroupPlacement = new AdGroupPlacementReport();
                        adGroupPlacement.AdGroupId = adGroupCriterionResult.getAdGroupId();

                        if (adGroupCriterionResult.getCriterion() instanceof Placement) {
                            Placement placement = (Placement)adGroupCriterionResult.getCriterion();

                            if (adGroupCriterionResult instanceof BiddableAdGroupCriterion) {
                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.BUDGET_OPTIMIZER) {
                                    adGroupPlacement.BiddingStrategyType = "BO";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.CONVERSION_OPTIMIZER) {
                                    adGroupPlacement.BiddingStrategyType = "CO";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPC) {
                                    adGroupPlacement.BiddingStrategyType = "MCPC";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPM) {
                                    adGroupPlacement.BiddingStrategyType = "MCPM";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.PERCENT_CPA) {
                                    adGroupPlacement.BiddingStrategyType = "PCPA";
                                }

                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBids() != null) {
                                    for (Bids bid : ((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBids()) {
                                        if (bid instanceof CpcBid) {
                                            if (((CpcBid)bid).getBid() != null) {
                                                adGroupPlacement.CpcBid = (double)((CpcBid)bid).getBid().getMicroAmount() / (double)1000000;
                                            }
                                        } else if (bid instanceof CpmBid) {
                                            if (((CpmBid)bid).getBid() != null) {
                                                adGroupPlacement.CpmBid = (double)((CpmBid)bid).getBid().getMicroAmount() / (double)1000000;
                                            }
                                        } else if (bid instanceof PercentCpaBid) {
                                            adGroupPlacement.PercentCpaBid = ((PercentCpaBid)bid).getBid();
                                        }
                                    }
                                }

                                adGroupPlacement.DestinationUrl = ((BiddableAdGroupCriterion)adGroupCriterionResult).getDestinationUrl();

                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.ENABLED) {
                                    adGroupPlacement.Status = "A";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.PAUSED) {
                                    adGroupPlacement.Status = "P";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.REMOVED) {
                                    adGroupPlacement.Status = "D";
                                }
                            }

                            if (adGroupCriterionResult.getCriterionUse() == CriterionUse.BIDDABLE) {
                                adGroupPlacement.CriterionUse = "B";
                            } else if (adGroupCriterionResult.getCriterionUse() == CriterionUse.NEGATIVE) {
                                adGroupPlacement.CriterionUse = "N";
                            }

                            adGroupPlacement.Id = adGroupCriterionResult.getCriterion().getId();

                            adGroupPlacement.PlacementUrl = placement.getUrl();

                            result.add(adGroupPlacement);
                        }
                    }
                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (Exception exc) {
            throw exc;
        }

        return result;
    }

    protected ArrayList<AdGroupTopicReport> GetAdGroupTopicsExc(String clientId) throws Exception{


        ArrayList<AdGroupTopicReport> result = new ArrayList<AdGroupTopicReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get AdGroup Service
        AdGroupCriterionServiceInterface adGroupCriterionService = sf.GetAdGroupCriterionService(clientId);

        int offset = 0;

        // Create selector.
        Selector selector = new Selector();
        selector.setFields(new String[]{
                "BiddingStrategyType",
                "CpcBid",
                "CpmBid",
                "CriterionUse",
                "DestinationUrl",
                "Id",
                "VerticalId",
                "VerticalParentId",
                "Path",
                "PercentCpaBid",
                "Status"
        });
        selector.setOrdering(new OrderBy[]{new OrderBy("AdGroupId", SortOrder.ASCENDING)});
        selector.setPaging(new Paging(offset, PAGE_SIZE));

        // Create predicates.
        /*Predicate adGroupIdPredicate =
                new Predicate("AdGroupId", PredicateOperator.IN, new String[]{adGroupId.toString()});*/
        Predicate criteriaTypePredicate =
                new Predicate("CriteriaType", PredicateOperator.EQUALS, new String[]{"VERTICAL"});
        selector.setPredicates(new Predicate[]{ criteriaTypePredicate});

        AdGroupCriterionPage page = null;
        try {

            do {

                page = adGroupCriterionService.get(selector);

                if (page.getEntries() != null && page.getEntries().length > 0) {
                    // Display results.
                    for (AdGroupCriterion adGroupCriterionResult : page.getEntries()) {

                        AdGroupTopicReport adGroupTopic = new AdGroupTopicReport();

                        adGroupTopic.AdGroupId = adGroupCriterionResult.getAdGroupId();

                        if (adGroupCriterionResult.getCriterion() instanceof Vertical) {
                            Vertical vertical = (Vertical)adGroupCriterionResult.getCriterion();

                            if (adGroupCriterionResult instanceof BiddableAdGroupCriterion) {
                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.BUDGET_OPTIMIZER) {
                                    adGroupTopic.BiddingStrategyType = "BO";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.CONVERSION_OPTIMIZER) {
                                    adGroupTopic.BiddingStrategyType = "CO";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPC) {
                                    adGroupTopic.BiddingStrategyType = "MCPC";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPM) {
                                    adGroupTopic.BiddingStrategyType = "MCPM";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.PERCENT_CPA) {
                                    adGroupTopic.BiddingStrategyType = "PCPA";
                                }

                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBids() != null) {
                                    for (Bids bid : ((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBids()) {
                                        if (bid instanceof CpcBid) {
                                            if (((CpcBid)bid).getBid() != null) {
                                                adGroupTopic.CpcBid = (double)((CpcBid)bid).getBid().getMicroAmount() / (double)1000000;
                                            }
                                        } else if (bid instanceof CpmBid) {
                                            if (((CpmBid)bid).getBid() != null) {
                                                adGroupTopic.CpmBid = (double)((CpmBid)bid).getBid().getMicroAmount() / (double)1000000;
                                            }
                                        } else if (bid instanceof PercentCpaBid) {
                                            adGroupTopic.PercentCpaBid = ((PercentCpaBid)bid).getBid();
                                        }
                                    }
                                }

                                adGroupTopic.DestinationUrl = ((BiddableAdGroupCriterion)adGroupCriterionResult).getDestinationUrl();

                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.ENABLED) {
                                    adGroupTopic.Status = "A";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.PAUSED) {
                                    adGroupTopic.Status = "P";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.REMOVED) {
                                    adGroupTopic.Status = "D";
                                }
                            }

                            if (adGroupCriterionResult.getCriterionUse() == CriterionUse.BIDDABLE) {
                                adGroupTopic.CriterionUse = "B";
                            } else if (adGroupCriterionResult.getCriterionUse() == CriterionUse.NEGATIVE) {
                                adGroupTopic.CriterionUse = "N";
                            }

                            adGroupTopic.Id = adGroupCriterionResult.getCriterion().getId();

                            adGroupTopic.VerticalId = vertical.getVerticalId();

                            result.add(adGroupTopic);
                        }
                    }
                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (Exception exc) {
            throw exc;
        }

        return result;
    }

    protected ArrayList<AdGroupInterestReport> GetAdGroupInterestsExc(String clientId) throws Exception{


        ArrayList<AdGroupInterestReport> result = new ArrayList<AdGroupInterestReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get AdGroup Service
        AdGroupCriterionServiceInterface adGroupCriterionService = sf.GetAdGroupCriterionService(clientId);

        int offset = 0;

        // Create selector.
        Selector selector = new Selector();
        selector.setFields(new String[]{
                "BiddingStrategyType",
                "CpcBid",
                "CpmBid",
                "CriterionUse",
                "DestinationUrl",
                "Id",
                "UserInterestId",
                "UserInterestName",
                "PercentCpaBid",
                "Status"
        });
        selector.setOrdering(new OrderBy[]{new OrderBy("AdGroupId", SortOrder.ASCENDING)});
        selector.setPaging(new Paging(offset, PAGE_SIZE));

        // Create predicates.
        /*Predicate adGroupIdPredicate =
                new Predicate("AdGroupId", PredicateOperator.IN, new String[]{adGroupId.toString()});*/
        Predicate criteriaTypePredicate =
                new Predicate("CriteriaType", PredicateOperator.EQUALS, new String[]{"USER_INTEREST"});
        selector.setPredicates(new Predicate[]{criteriaTypePredicate});

        AdGroupCriterionPage page = null;
        try {

            do {

                page = adGroupCriterionService.get(selector);

                if (page.getEntries() != null && page.getEntries().length > 0) {
                    // Display results.
                    for (AdGroupCriterion adGroupCriterionResult : page.getEntries()) {

                        AdGroupInterestReport adGroupInterest = new AdGroupInterestReport();
                        adGroupInterest.AdGroupId = adGroupCriterionResult.getAdGroupId();

                        if (adGroupCriterionResult.getCriterion() instanceof CriterionUserInterest) {
                            CriterionUserInterest userInterest = (CriterionUserInterest)adGroupCriterionResult.getCriterion();

                            if (adGroupCriterionResult instanceof BiddableAdGroupCriterion) {
                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.BUDGET_OPTIMIZER) {
                                    adGroupInterest.BiddingStrategyType = "BO";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.CONVERSION_OPTIMIZER) {
                                    adGroupInterest.BiddingStrategyType = "CO";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPC) {
                                    adGroupInterest.BiddingStrategyType = "MCPC";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPM) {
                                    adGroupInterest.BiddingStrategyType = "MCPM";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.PERCENT_CPA) {
                                    adGroupInterest.BiddingStrategyType = "PCPA";
                                }

                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBids() != null) {
                                    for (Bids bid : ((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBids()) {
                                        if (bid instanceof CpcBid) {
                                            if (((CpcBid)bid).getBid() != null) {
                                                adGroupInterest.CpcBid = (double)((CpcBid)bid).getBid().getMicroAmount() / (double)1000000;
                                            }
                                        } else if (bid instanceof CpmBid) {
                                            if (((CpmBid)bid).getBid() != null) {
                                                adGroupInterest.CpmBid = (double)((CpmBid)bid).getBid().getMicroAmount() / (double)1000000;
                                            }
                                        } else if (bid instanceof PercentCpaBid) {
                                            adGroupInterest.PercentCpaBid = ((PercentCpaBid)bid).getBid();
                                        }
                                    }
                                }

                                adGroupInterest.DestinationUrl = ((BiddableAdGroupCriterion)adGroupCriterionResult).getDestinationUrl();

                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.ENABLED) {
                                    adGroupInterest.Status = "A";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.PAUSED) {
                                    adGroupInterest.Status = "P";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.REMOVED) {
                                    adGroupInterest.Status = "D";
                                }
                            }

                            if (adGroupCriterionResult.getCriterionUse() == CriterionUse.BIDDABLE) {
                                adGroupInterest.CriterionUse = "B";
                            } else if (adGroupCriterionResult.getCriterionUse() == CriterionUse.NEGATIVE) {
                                adGroupInterest.CriterionUse = "N";
                            }

                            adGroupInterest.Id = adGroupCriterionResult.getCriterion().getId();

                            adGroupInterest.UserInterestId = userInterest.getUserInterestId();

                            result.add(adGroupInterest);
                        }
                    }
                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (Exception exc) {
            throw exc;
        }

        return result;
    }

    protected ArrayList<AdGroupGenderReport> GetAdGroupGendersExc(String clientId) throws Exception{


        ArrayList<AdGroupGenderReport> result = new ArrayList<AdGroupGenderReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get AdGroup Service
        AdGroupCriterionServiceInterface adGroupCriterionService = sf.GetAdGroupCriterionService(clientId);

        int offset = 0;

        // Create selector.
        Selector selector = new Selector();
        selector.setFields(new String[]{
                "BiddingStrategyType",
                "CpcBid",
                "CpmBid",
                "CriterionUse",
                "DestinationUrl",
                "Id",
                "GenderType",
                "PercentCpaBid",
                "Status"
        });
        selector.setOrdering(new OrderBy[]{new OrderBy("AdGroupId", SortOrder.ASCENDING)});
        selector.setPaging(new Paging(offset, PAGE_SIZE));

        // Create predicates.
        /*Predicate adGroupIdPredicate =
                new Predicate("AdGroupId", PredicateOperator.IN, new String[]{adGroupId.toString()});*/
        Predicate criteriaTypePredicate =
                new Predicate("CriteriaType", PredicateOperator.EQUALS, new String[]{"GENDER"});
        selector.setPredicates(new Predicate[]{criteriaTypePredicate});

        AdGroupCriterionPage page = null;
        try {

            do {

                page = adGroupCriterionService.get(selector);

                if (page.getEntries() != null && page.getEntries().length > 0) {
                    // Display results.
                    for (AdGroupCriterion adGroupCriterionResult : page.getEntries()) {

                        AdGroupGenderReport adGroupGender = new AdGroupGenderReport();
                        adGroupGender.AdGroupId = adGroupCriterionResult.getAdGroupId();

                        if (adGroupCriterionResult.getCriterion() instanceof Gender) {
                            Gender gender = (Gender)adGroupCriterionResult.getCriterion();

                            if (adGroupCriterionResult instanceof BiddableAdGroupCriterion) {
                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.BUDGET_OPTIMIZER) {
                                    adGroupGender.BiddingStrategyType = "BO";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.CONVERSION_OPTIMIZER) {
                                    adGroupGender.BiddingStrategyType = "CO";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPC) {
                                    adGroupGender.BiddingStrategyType = "MCPC";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPM) {
                                    adGroupGender.BiddingStrategyType = "MCPM";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.PERCENT_CPA) {
                                    adGroupGender.BiddingStrategyType = "PCPA";
                                }

                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBids() != null) {
                                    for (Bids bid : ((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBids()) {
                                        if (bid instanceof CpcBid) {
                                            if (((CpcBid)bid).getBid() != null) {
                                                adGroupGender.CpcBid = (double)((CpcBid)bid).getBid().getMicroAmount() / (double)1000000;
                                            }
                                        } else if (bid instanceof CpmBid) {
                                            if (((CpmBid)bid).getBid() != null) {
                                                adGroupGender.CpmBid = (double)((CpmBid)bid).getBid().getMicroAmount() / (double)1000000;
                                            }
                                        } else if (bid instanceof PercentCpaBid) {
                                            adGroupGender.PercentCpaBid = ((PercentCpaBid)bid).getBid();
                                        }
                                    }
                                }

                                adGroupGender.DestinationUrl = ((BiddableAdGroupCriterion)adGroupCriterionResult).getDestinationUrl();

                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.ENABLED) {
                                    adGroupGender.Status = "A";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.PAUSED) {
                                    adGroupGender.Status = "P";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.REMOVED) {
                                    adGroupGender.Status = "D";
                                }
                            }

                            if (adGroupCriterionResult.getCriterionUse() == CriterionUse.BIDDABLE) {
                                adGroupGender.CriterionUse = "B";
                            } else if (adGroupCriterionResult.getCriterionUse() == CriterionUse.NEGATIVE) {
                                adGroupGender.CriterionUse = "N";
                            }

                            adGroupGender.Id = adGroupCriterionResult.getCriterion().getId();

                            adGroupGender.GenderType = gender.getGenderType().getValue();

                            result.add(adGroupGender);
                        }
                    }
                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (Exception exc) {
            throw exc;
        }

        return result;
    }

    protected ArrayList<AdGroupAgeReport> GetAdGroupAgesExc(String clientId) throws Exception{


        ArrayList<AdGroupAgeReport> result = new ArrayList<AdGroupAgeReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get AdGroup Service
        AdGroupCriterionServiceInterface adGroupCriterionService = sf.GetAdGroupCriterionService(clientId);

        int offset = 0;

        // Create selector.
        Selector selector = new Selector();
        selector.setFields(new String[]{
                "BiddingStrategyType",
                "CpcBid",
                "CpmBid",
                "CriterionUse",
                "DestinationUrl",
                "Id",
                "AgeRangeType",
                "PercentCpaBid",
                "Status"
        });
        selector.setOrdering(new OrderBy[]{new OrderBy("AdGroupId", SortOrder.ASCENDING)});
        selector.setPaging(new Paging(offset, PAGE_SIZE));

        // Create predicates.
        /*Predicate adGroupIdPredicate =
                new Predicate("AdGroupId", PredicateOperator.IN, new String[]{adGroupId.toString()});*/
        Predicate criteriaTypePredicate =
                new Predicate("CriteriaType", PredicateOperator.EQUALS, new String[]{"AGE_RANGE"});
        selector.setPredicates(new Predicate[]{criteriaTypePredicate});

        AdGroupCriterionPage page = null;
        try {

            do {

                page = adGroupCriterionService.get(selector);

                if (page.getEntries() != null && page.getEntries().length > 0) {
                    // Display results.
                    for (AdGroupCriterion adGroupCriterionResult : page.getEntries()) {

                        AdGroupAgeReport adGroupAge = new AdGroupAgeReport();
                        adGroupAge.AdGroupId = adGroupCriterionResult.getAdGroupId();

                        if (adGroupCriterionResult.getCriterion() instanceof AgeRange) {
                            AgeRange ageRange = (AgeRange)adGroupCriterionResult.getCriterion();

                            if (adGroupCriterionResult instanceof BiddableAdGroupCriterion) {
                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.BUDGET_OPTIMIZER) {
                                    adGroupAge.BiddingStrategyType = "BO";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.CONVERSION_OPTIMIZER) {
                                    adGroupAge.BiddingStrategyType = "CO";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPC) {
                                    adGroupAge.BiddingStrategyType = "MCPC";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.MANUAL_CPM) {
                                    adGroupAge.BiddingStrategyType = "MCPM";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBiddingStrategyType() == BiddingStrategyType.PERCENT_CPA) {
                                    adGroupAge.BiddingStrategyType = "PCPA";
                                }

                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBids() != null) {
                                    for (Bids bid : ((BiddableAdGroupCriterion)adGroupCriterionResult).getBiddingStrategyConfiguration().getBids()) {
                                        if (bid instanceof CpcBid) {
                                            if (((CpcBid)bid).getBid() != null) {
                                                adGroupAge.CpcBid = (double)((CpcBid)bid).getBid().getMicroAmount() / (double)1000000;
                                            }
                                        } else if (bid instanceof CpmBid) {
                                            if (((CpmBid)bid).getBid() != null) {
                                                adGroupAge.CpmBid = (double)((CpmBid)bid).getBid().getMicroAmount() / (double)1000000;
                                            }
                                        } else if (bid instanceof PercentCpaBid) {
                                            adGroupAge.PercentCpaBid = ((PercentCpaBid)bid).getBid();
                                        }
                                    }
                                }

                                adGroupAge.DestinationUrl = ((BiddableAdGroupCriterion)adGroupCriterionResult).getDestinationUrl();

                                if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.ENABLED) {
                                    adGroupAge.Status = "A";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.PAUSED) {
                                    adGroupAge.Status = "P";
                                } else if (((BiddableAdGroupCriterion)adGroupCriterionResult).getUserStatus() == UserStatus.REMOVED) {
                                    adGroupAge.Status = "D";
                                }
                            }

                            if (adGroupCriterionResult.getCriterionUse() == CriterionUse.BIDDABLE) {
                                adGroupAge.CriterionUse = "B";
                            } else if (adGroupCriterionResult.getCriterionUse() == CriterionUse.NEGATIVE) {
                                adGroupAge.CriterionUse = "N";
                            }

                            adGroupAge.Id = adGroupCriterionResult.getCriterion().getId();

                            adGroupAge.AgeRangeType = ageRange.getAgeRangeType().getValue();

                            result.add(adGroupAge);
                        }
                    }
                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (Exception exc) {
            throw exc;
        }

        return result;
    }

    protected AccountReport GetAccountReportExc(String clientId) throws Exception{

        AccountReport result = new AccountReport();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get Managed Customer Service
        ManagedCustomerServiceInterface managedCustomerService = sf.GetManagedCustomerService(clientId);

        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));
        //selector.setOrdering(new OrderBy[] {new OrderBy("Name", SortOrder.ASCENDING)});

        selector.setFields(new String[]{
                "CurrencyCode",
                "CustomerId",
                "DateTimeZone",
                "Name"
        });


        // Create predicates.
        Predicate accountIdPredicate =
                new Predicate("CustomerId", PredicateOperator.IN, new String[]{clientId});
        selector.setPredicates(new Predicate[]{accountIdPredicate});

        ManagedCustomerPage page = null;


        try {

            do {

                page = managedCustomerService.get(selector);

                if (page.getEntries() != null) {

                    for (ManagedCustomer managedCustomer : page.getEntries()) {
                        result.CurrencyCode = managedCustomer.getCurrencyCode();
                        result.CustomerId = managedCustomer.getCustomerId();
                        result.DateTimeZone = managedCustomer.getDateTimeZone();
                        result.Name = managedCustomer.getName();
                    }


                }


                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (Exception exc) {
            throw exc;
        }

        return result;
    }

    public ArrayList<FeedReport> GetAllFeedsReportExc(String clientId) throws Exception{
        try{
            String result = "";
            GA_Report res = new GA_Report();

            // Get the instance of service's factory
            ServiceFactory sf = ServiceFactory.getInstance();
            //ArrayList<GA_ResultItem> feeds = new ArrayList<GA_ResultItem>();
            FeedMappingServiceInterface feedMappingService = sf.GetFeedMappingServiceInterface(clientId);
            int offset = 0;
            Selector selector = new Selector();

            selector.setPaging(new Paging(offset, PAGE_SIZE));


            selector.setFields(new String[]{"FeedId", "FeedMappingId", "PlaceholderType", "Status", "AttributeFieldMappings"});

            Predicate predicate = new Predicate("Status", PredicateOperator.NOT_EQUALS, new String[] {"REMOVED"});
            Predicate[] predicates = new Predicate[] {predicate};
            //selector.setPredicates(predicates);

            FeedMappingPage page = null;

            ArrayList<FeedReport> feeds = new ArrayList<FeedReport>();

            try {
                do {
                    page = feedMappingService.get(selector);
                    if (page.getEntries() != null) {
                        for (FeedMapping feedMapping : page.getEntries()) {
                            FeedReport feedReport = new FeedReport();
                            feedReport.FeedId = feedMapping.getFeedId();
                            feedReport.FeedStatus = feedMapping.getStatus().getValue().substring(0, 1);
                            feedReport.FeedType = feedMapping.getPlaceholderType();
                            feedReport.FeedAttributes = new ArrayList<FeedAttributeReport>();

                            for (AttributeFieldMapping fieldMapping : feedMapping.getAttributeFieldMappings()){

                                FeedAttributeReport feedAttributeReport = new FeedAttributeReport();
                                feedAttributeReport.FieldId = fieldMapping.getFieldId();
                                feedAttributeReport.FeedAttributeId = fieldMapping.getFeedAttributeId();

                                feedReport.FeedAttributes.add(feedAttributeReport);
                            }
                            feeds.add(feedReport);
                        }
                    }
                    offset += PAGE_SIZE;
                    selector.getPaging().setStartIndex(offset);
                } while (offset < page.getTotalNumEntries());


            } catch (RemoteException e) {
                throw e;
            }

            //res.Feeds = feeds;

            //res.Items.add(resultItem);


            return feeds;


        }   catch (Exception exc){

            throw exc;

        }

    }

    public ArrayList<GA_SitelinksFeedItem> GetSitelinksFeedItemReportExc(String accountId) throws Exception{

        ArrayList<GA_SitelinksFeedItem> result = new ArrayList<GA_SitelinksFeedItem>();
        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        FeedMappingServiceInterface feedMappingService = sf.GetFeedMappingServiceInterface(accountId);
        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));

        Predicate feedTypePredicate = new Predicate("PlaceholderType", PredicateOperator.IN, new String[]{"1"});
        Predicate statusPredicate = new Predicate("Status", PredicateOperator.NOT_EQUALS, new String[] {"REMOVED"});

        selector.setPredicates(new Predicate[]{feedTypePredicate, statusPredicate});
        selector.setFields(new String[]{"FeedId", "FeedMappingId", "PlaceholderType", "Status", "AttributeFieldMappings"});

        FeedMappingPage page = null;

        //ArrayList<FeedReport> feeds = new ArrayList<FeedReport>();

        try {

            do {

                page = feedMappingService.get(selector);

                if (page.getEntries() != null) {

                    for (FeedMapping feedMapping : page.getEntries()) {

                        //if (!feedMapping.getFeedId().equals(feedMapping.getFeedMappingId())){

                        GA_SitelinksFeedItem feedItem = new GA_SitelinksFeedItem();

                        feedItem.FeedId = feedMapping.getFeedId();
                        feedItem.FeedItems = new ArrayList<SitelinksFeedItem>();

                        feedItem.FeedItems = GetFeedItemsByFeedExc(accountId, feedItem.FeedId);

                        result.add(feedItem);
                        //}

                    }

                }

                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (RemoteException e) {
           throw e;
        }

        return result;
    }

    public ArrayList<GA_LocationExtensionsFeedItem> GetLocationExtensionsFeedItemReportExc(String accountId) throws Exception{



        ArrayList<GA_LocationExtensionsFeedItem> result = new ArrayList<GA_LocationExtensionsFeedItem>();
        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        FeedMappingServiceInterface feedMappingService = sf.GetFeedMappingServiceInterface(accountId);
        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));

        Predicate feedTypePredicate = new Predicate("PlaceholderType", PredicateOperator.IN, new String[]{"7"});
        Predicate statusPredicate = new Predicate("Status", PredicateOperator.NOT_EQUALS, new String[] {"REMOVED"});

        selector.setPredicates(new Predicate[]{feedTypePredicate, statusPredicate});
        selector.setFields(new String[]{"FeedId", "FeedMappingId", "PlaceholderType", "Status", "AttributeFieldMappings"});

        FeedMappingPage page = null;

        //ArrayList<FeedReport> feeds = new ArrayList<FeedReport>();

        try {

            do {

                page = feedMappingService.get(selector);

                if (page.getEntries() != null) {

                    for (FeedMapping feedMapping : page.getEntries()) {

                        //if (!feedMapping.getFeedId().equals(feedMapping.getFeedMappingId())){

                        GA_LocationExtensionsFeedItem feedItem = new GA_LocationExtensionsFeedItem();

                        feedItem.FeedId = feedMapping.getFeedId();
                        feedItem.FeedItems = new ArrayList<LocationExtensionsFeedItem>();

                        feedItem.FeedItems = GetFeedItemsLocationsByFeed(accountId, feedItem.FeedId);

                        result.add(feedItem);
                        //}

                    }

                }

                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (RemoteException e) {
           throw e;
        }

        return result;
    }

    public ArrayList<GA_CallsFeedItem> GetCallsFeedItemReportExc(String accountId) throws Exception{

        ArrayList<GA_CallsFeedItem> result = new ArrayList<GA_CallsFeedItem>();
        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        FeedMappingServiceInterface feedMappingService = sf.GetFeedMappingServiceInterface(accountId);
        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));

        Predicate feedTypePredicate = new Predicate("PlaceholderType", PredicateOperator.IN, new String[]{"2"});
        Predicate statusPredicate = new Predicate("Status", PredicateOperator.NOT_EQUALS, new String[] {"REMOVED"});

        selector.setPredicates(new Predicate[]{feedTypePredicate, statusPredicate});
        selector.setFields(new String[]{"FeedId", "FeedMappingId", "PlaceholderType", "Status", "AttributeFieldMappings"});

        FeedMappingPage page = null;

        //ArrayList<FeedReport> feeds = new ArrayList<FeedReport>();

        try {

            do {

                page = feedMappingService.get(selector);

                if (page.getEntries() != null) {

                    for (FeedMapping feedMapping : page.getEntries()) {

                        //if (!feedMapping.getFeedId().equals(feedMapping.getFeedMappingId())){

                        GA_CallsFeedItem feedItem = new GA_CallsFeedItem();

                        feedItem.FeedId = feedMapping.getFeedId();
                        feedItem.FeedItems = new ArrayList<CallsFeedItem>();

                        feedItem.FeedItems = GetFeedItemsCallsByFeedExc(accountId, feedItem.FeedId);

                        result.add(feedItem);
                        //}

                    }

                }

                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (RemoteException e) {
           throw e;
        }

        return result;
    }

    public ArrayList<LocationReport> GetLocationsExc(String clientId) throws Exception{
        ArrayList<LocationReport> result = new ArrayList<LocationReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get Campaign Criterion Service
        CampaignCriterionServiceInterface campaignCriterionService = sf.GetCampaignCriterionService(clientId);

        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));
        //selector.setOrdering(new OrderBy[] {new OrderBy("Name", SortOrder.ASCENDING)});

        selector.setFields(new String[]{
                "DisplayType",
                "Id",
                "LocationName",
                "ParentLocations",
                "TargetingStatus"
        });

        // Create predicates.
        Predicate criterionTypePredicate =
                new Predicate("CriteriaType", PredicateOperator.EQUALS, new String[]{"LOCATION"});
        selector.setPredicates(new Predicate[]{criterionTypePredicate});

        CampaignCriterionPage page = null;

        try {
            do {
                page = campaignCriterionService.get(selector);
                if (page.getEntries() != null) {
                    for (CampaignCriterion campaignCriterion : page.getEntries()) {
                        if (campaignCriterion.getCriterion() instanceof Location) {
                            LocationReport locationReport = new LocationReport();

                            Location location = (Location) campaignCriterion.getCriterion();

                            locationReport.CampaignId = campaignCriterion.getCampaignId();
                            locationReport.DisplayType = location.getDisplayType();
                            locationReport.Id = location.getId();
                            locationReport.LocationName = location.getLocationName();

                            if (location.getTargetingStatus() == LocationTargetingStatus.ACTIVE) {
                                locationReport.TargetingStatus = "A";
                            } else if (location.getTargetingStatus() == LocationTargetingStatus.OBSOLETE) {
                                locationReport.TargetingStatus = "O";
                            } else if (location.getTargetingStatus() == LocationTargetingStatus.PHASING_OUT) {
                                locationReport.TargetingStatus = "P";
                            }

                            if (location.getParentLocations() != null){
                                locationReport.ParentIds = new long[location.getParentLocations().length];
                                for (int i = 0; i < location.getParentLocations().length; i++) {
                                    locationReport.ParentIds[i] = location.getParentLocations()[i].getId();
                                }
                            }

                            result.add(locationReport);
                        }
                    }
                }

                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (Exception exc) {
           throw exc;
        }

        return result;
    }

    private ArrayList<Long> GetFeedIds(String clientId, String placeHolderType) throws Exception{
        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();
        FeedItemServiceInterface feedItemService = sf.GetFeedItemServiceInterface(clientId);


        FeedMappingServiceInterface feedMappingService = sf.GetFeedMappingServiceInterface(clientId);
        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));

        Predicate feedTypePredicate =
                new Predicate("PlaceholderType", PredicateOperator.IN, new String[]{placeHolderType});

        selector.setPredicates(new Predicate[]{feedTypePredicate});
        selector.setFields(new String[]{"FeedId", "PlaceholderType", "Status"});

        FeedMappingPage page = null;

        ArrayList<Long> feedIds = new ArrayList<Long>();

        try {
            do {
                page = feedMappingService.get(selector);
                if (page.getEntries() != null) {
                    for (FeedMapping feedMapping : page.getEntries()) {

                        if (!(feedIds.contains(feedMapping.getFeedId())))
                            feedIds.add(feedMapping.getFeedId());
                    }
                }

                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);
            } while (offset < page.getTotalNumEntries());
        } catch (RemoteException e) {
            throw e;  //To change body of catch statement use File | Settings | File Templates.
        }

        return feedIds;
    }

    private CampaignFeedMapping GetCampaignFeedMapping(ArrayList<CampaignFeedMapping> feedMappings, Long campaignId){
        CampaignFeedMapping result = null;
        for (CampaignFeedMapping cfm : feedMappings){
            if (cfm.CampaignId == campaignId){
                return cfm;
            }
        }
        return result;
    }

    protected ArrayList<CallsAdExtensionReport> GetFeedItemsAdExtensionsCallsReportExc(String clientId) throws Exception{

        ArrayList<CallsAdExtensionReport> result = new ArrayList<CallsAdExtensionReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();
        //FeedItemServiceInterface feedItemService = sf.GetFeedItemServiceInterface(clientId);

        //ArrayList<Long> feedIds = GetFeedIds(clientId, "1");

        ArrayList<CampaignFeedMapping> feedsByCampaign = GetFeedsByCampaignExc(clientId, "2");

        CallsAdExtensionReport calls = new CallsAdExtensionReport();
        calls.Calls = feedsByCampaign;


        result.add(calls);

        return result;
    }

    private ArrayList<CallsFeedItem> GetFeedItemsCallsByFeedExc(String clientId, Long feedId) throws Exception{
        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();
        FeedItemServiceInterface feedItemService = sf.GetFeedItemServiceInterface(clientId);

        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));

        Predicate feedIdPredicate =
                new Predicate("FeedId", PredicateOperator.IN, new String[]{feedId.toString()});

        selector.setPredicates(new Predicate[]{feedIdPredicate});
        selector.setFields(new String[]{"FeedId", "FeedItemId", "AttributeValues", "Status"});

        FeedItemPage page = null;

        ArrayList<CallsFeedItem> result = new ArrayList<CallsFeedItem>();


        try {

            do {

                page = feedItemService.get(selector);


                if (page.getEntries() != null) {

                    for (FeedItem feedItem : page.getEntries()) {

                        CallsFeedItem fi = new CallsFeedItem();

                        fi.FeedItemId = feedItem.getFeedItemId();
                        fi.FeedStatus = feedItem.getStatus().getValue().substring(0, 1);
                        fi.FeedAttributes = new ArrayList<GA_FeedAttribute>();

                        for (FeedItemAttributeValue attValue : feedItem.getAttributeValues()){
                            GA_FeedAttribute attribute = new GA_FeedAttribute();
                            attribute.FeedAttrId = attValue.getFeedAttributeId();
                            if (attValue.getBooleanValue() != null){
                                attribute.FeedItemValue = attValue.getBooleanValue().toString();
                            }else if (attValue.getDoubleValue() != null){
                                attribute.FeedItemValue = attValue.getDoubleValue().toString();
                            }else if (attValue.getStringValue() != null){
                                attribute.FeedItemValue = attValue.getStringValue().toString();
                            }else if (attValue.getIntegerValue() != null){
                                attribute.FeedItemValue = attValue.getIntegerValue().toString();
                            }

                            fi.FeedAttributes.add(attribute);

                        }
                        result.add(fi);

                    }



                }

                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (RemoteException e) {
            throw e;
        }

        return result;
    }

    private ArrayList<LocationExtensionsFeedItem> GetFeedItemsLocationsByFeed(String accountId, Long feedId) throws Exception{
        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();
        FeedItemServiceInterface feedItemService = sf.GetFeedItemServiceInterface(accountId);

        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));

        Predicate feedIdPredicate =
                new Predicate("FeedId", PredicateOperator.IN, new String[]{feedId.toString()});

        selector.setPredicates(new Predicate[]{feedIdPredicate});
        selector.setFields(new String[]{"FeedId", "FeedItemId", "AttributeValues", "Status"});

        FeedItemPage page = null;

        ArrayList<LocationExtensionsFeedItem> result = new ArrayList<LocationExtensionsFeedItem>();


        try {

            do {

                page = feedItemService.get(selector);


                if (page.getEntries() != null) {

                    for (FeedItem feedItem : page.getEntries()) {

                        LocationExtensionsFeedItem fi = new LocationExtensionsFeedItem();

                        fi.FeedItemId = feedItem.getFeedItemId();
                        fi.FeedStatus = feedItem.getStatus().getValue().substring(0, 1);
                        fi.FeedAttributes = new ArrayList<GA_FeedAttribute>();

                        for (FeedItemAttributeValue attValue : feedItem.getAttributeValues()){
                            GA_FeedAttribute attribute = new GA_FeedAttribute();
                            attribute.FeedAttrId = attValue.getFeedAttributeId();
                            if (attValue.getBooleanValue() != null){
                                attribute.FeedItemValue = attValue.getBooleanValue().toString();
                            }else if (attValue.getDoubleValue() != null){
                                attribute.FeedItemValue = attValue.getDoubleValue().toString();
                            }else if (attValue.getStringValue() != null){
                                attribute.FeedItemValue = attValue.getStringValue().toString();
                            }else if (attValue.getIntegerValue() != null){
                                attribute.FeedItemValue = attValue.getIntegerValue().toString();
                            }

                            fi.FeedAttributes.add(attribute);

                        }
                        result.add(fi);

                    }



                }

                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (RemoteException e) {
           throw e;
        }

        return result;

    }

    private ArrayList<SitelinksFeedItem> GetFeedItemsByFeedExc(String accountId, Long feedId) throws Exception{
        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();
        FeedItemServiceInterface feedItemService = sf.GetFeedItemServiceInterface(accountId);

        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));

        Predicate feedIdPredicate =
                new Predicate("FeedId", PredicateOperator.IN, new String[]{feedId.toString()});
        Predicate statusPredicate = new Predicate("Status", PredicateOperator.NOT_EQUALS, new String[] {"REMOVED"});

        selector.setPredicates(new Predicate[]{feedIdPredicate, statusPredicate});
        selector.setFields(new String[]{"FeedId", "FeedItemId", "AttributeValues", "Status"});

        FeedItemPage page = null;

        ArrayList<SitelinksFeedItem> result = new ArrayList<SitelinksFeedItem>();


        try {

            do {

                page = feedItemService.get(selector);


                if (page.getEntries() != null) {

                    for (FeedItem feedItem : page.getEntries()) {

                        SitelinksFeedItem fi = new SitelinksFeedItem();

                        fi.FeedItemId = feedItem.getFeedItemId();
                        fi.FeedStatus = feedItem.getStatus().getValue().substring(0, 1);
                        fi.FeedAttributes = new ArrayList<GA_FeedAttribute>();

                        for (FeedItemAttributeValue attValue : feedItem.getAttributeValues()){
                            GA_FeedAttribute attribute = new GA_FeedAttribute();
                            attribute.FeedAttrId = attValue.getFeedAttributeId();
                            if (attValue.getBooleanValue() != null){
                                attribute.FeedItemValue = attValue.getBooleanValue().toString();

                            }else if (attValue.getDoubleValue() != null){
                                attribute.FeedItemValue = attValue.getDoubleValue().toString();
                            }else if (attValue.getStringValue() != null){
                                attribute.FeedItemValue = attValue.getStringValue().toString();
                            }else if (attValue.getIntegerValue() != null){
                                attribute.FeedItemValue = attValue.getIntegerValue().toString();
                            }
                            //System.out.println(attribute.FeedItemValue);
                            fi.FeedAttributes.add(attribute);

                        }
                        result.add(fi);
                        //System.out.println(fi.FeedStatus);

                    }



                }

                offset += PAGE_SIZE;
                selector.getPaging().setStartIndex(offset);

            } while (offset < page.getTotalNumEntries());


        } catch (RemoteException e) {
            throw e;
        }

        return result;
    }

    protected void getLocationsExtraDataExc(String clientId, ArrayList<LocationReport> locationReports) throws Exception{
        int locationsQty = 0;
        for (LocationReport locationReport : locationReports) {
            locationsQty += locationReport.ParentIds.length;
        }
        if (locationsQty > 0) {
            int pagesQty = (int)Math.ceil((float) locationsQty / (float) PAGE_SIZE);
            int page = 0;
            String[][] locationsIdsPages = new String[pagesQty][];
            locationsIdsPages[0] = new String[PAGE_SIZE];
            int i = 0;
            for (LocationReport locationReport : locationReports) {
                for (int j = 0; j < locationReport.ParentIds.length; j++) {
                    locationsIdsPages[page][i] = String.valueOf(locationReport.ParentIds[j]);
                    i++;
                    if (i >= PAGE_SIZE) {
                        i = 0;
                        page++;
                        if (page < pagesQty - 1) {
                            locationsIdsPages[page] = new String[PAGE_SIZE];
                        } else {
                            locationsIdsPages[page] = new String[locationsQty % PAGE_SIZE];
                        }
                    }
                }
            }

            for (i=0; i<locationsIdsPages.length; i++) {
                LocationCriterion[] locationCriterions = GetLocationsExc(clientId, locationsIdsPages[i]);

                if (locationCriterions != null) {
                    for (LocationCriterion locationCriterion : locationCriterions) {
                        String displayType = locationCriterion.getLocation().getDisplayType();
                        if (displayType.equals("State") || displayType.equals("Country")) {
                            for (LocationReport locationReport : locationReports) {
                                for (long parentId : locationReport.ParentIds) {
                                    if (parentId == locationCriterion.getLocation().getId()) {
                                        if (displayType.equals("State")) {
                                            locationReport.ProvinceCode = locationCriterion.getLocation().getLocationName();
                                        } else {
                                            locationReport.CountryCode = locationCriterion.getLocation().getLocationName();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    protected LocationCriterion[] GetLocationsExc(String clientId, String[] locationsIds) throws Exception{
        ArrayList<LocationReport> result = new ArrayList<LocationReport>();

        // Get the instance of service's factory
        ServiceFactory sf = ServiceFactory.getInstance();

        // Get Location Criterion Service
        LocationCriterionServiceInterface locationCriterionService = sf.GetLocationCriterionService(clientId);

        int offset = 0;
        Selector selector = new Selector();

        selector.setPaging(new Paging(offset, PAGE_SIZE));
        //selector.setOrdering(new OrderBy[] {new OrderBy("Name", SortOrder.ASCENDING)});

        selector.setFields(new String[]{
                "CanonicalName",
                "Reach"
        });

        // Create predicates.
        Predicate campaignIdPredicate =
                new Predicate("Id", PredicateOperator.IN, locationsIds);
        selector.setPredicates(new Predicate[]{campaignIdPredicate});

        try {
            return locationCriterionService.get(selector);
        } catch (Exception exc) {
            throw exc;
        }

    }



}

class GetTotalReportForClientExc extends Thread{
    private String clientId;
    private String locationFile;
    private int retries = 5;

    GetTotalReportForClientExc(String clientId, String locationFile, int retries){
        this.clientId = clientId;
        this.locationFile = locationFile;
        this.retries = retries;
    }

    public void run(){
        SyncManager sm = new SyncManager();

        int i = 0;

        while (i < retries){

            try {
                sm.GetTotalReportForClientExc(clientId, locationFile);
                i = retries;
            }catch (Exception e) {

                i++;

                if (i == retries) {

                    try {

                        String result = "";

                        GA_Report report = new GA_Report();
                        report.HasError = true;


                        ErrorsStruct es =  new ErrorsStruct();
                        com.genexususa.eo.google.data.Error error = new com.genexususa.eo.google.data.Error();


                        com.genexususa.eo.google.data.Error err = new com.genexususa.eo.google.data.Error();

                        StringWriter st = new StringWriter();
                        e.printStackTrace(new PrintWriter(st));

                        err.UnknownError = st.toString();

                        error.ErrorString = st.toString();
                        es.Message = e.getMessage();
                        es.Errors.add(error);

                        report.Errors = es;


                        JAXBContext contextObj = JAXBContext.newInstance(GA_Report.class);

                        Marshaller marshallerObj = contextObj.createMarshaller();
                        marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

                        StringWriter sw = new StringWriter();

                        marshallerObj.marshal(report, sw);
                        result = sw.getBuffer().toString();
                        //System.out.println(result);

                        FileWriter fw = new FileWriter(locationFile + File.separator + clientId + ".xml");
                        BufferedWriter bw = new BufferedWriter(fw);

                        bw.write(result);
                        bw.flush();
                        bw.close();

                    } catch (Exception exc) {
                        exc.printStackTrace();
                    }

                }

            }
        }
    }
}
